package com.lib.basex.utils;

import android.content.Context;
import android.os.Build;
import android.os.Environment;
import android.os.storage.StorageManager;
import android.os.storage.StorageVolume;
import android.text.TextUtils;

import androidx.annotation.RequiresApi;

import com.lib.basex.LApplication;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.lang.reflect.Array;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by Mouse on 2018/10/18.
 */
public class LFileUtils {

    /**
     * 获取APP 私有目录
     *
     * @return
     */
    public static String getDir() {
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
            return LApplication.app.getDataDir().getAbsolutePath();
        } else {
            return "/data/data/" + LApplication.app.getPackageName();
        }
    }

    public static String getFilename(String path) {
        if (TextUtils.isEmpty(path)) {
            return "";
        }
        int index = path.lastIndexOf("/");
        return path.substring(index + 1);
    }

    public static String getFileExt(String path) {
        if (path == null) {
            return null;
        }
        int index = path.lastIndexOf(".");
        if (index >= 0) {
            return path.substring(index + 1).toLowerCase();
        }
        return null;
    }

    public static String getFilenameByKeyHashCode(String url) {
        int firstHalfLength = url.length() / 2;
        String localFilename = String.valueOf(url.substring(0, firstHalfLength).hashCode());
        localFilename += String.valueOf(url.substring(firstHalfLength).hashCode());
        return localFilename;
    }

    public static List<String> readStringList(String path) {
        File file = new File(path);
        if (!file.exists()) {
            return null;
        }
        List<String> list = new ArrayList<>();
        try {
            FileReader fr = new FileReader(path);
            BufferedReader br = new BufferedReader(fr);
            String line;
            while ((line = br.readLine()) != null) {
                list.add(line);
            }
            br.close();
            fr.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return list;
    }

    public static boolean exist(String path) {
        if (TextUtils.isEmpty(path)) {
            return false;
        }
        return new File(path).exists();
    }

    public static boolean move(String src, String dest, boolean delOnExist) {
        if (TextUtils.isEmpty(src) || TextUtils.isEmpty(dest) || !exist(src)) {
            return false;
        }
        File fileDest = new File(dest);
        if (!fileDest.exists()) {
            boolean mkdirs = fileDest.mkdirs();
            if (!mkdirs) {
                return false;
            }
        }
        if (fileDest.isFile()) {
            return false;
        }

        String filename = getFilename(src);
        String destFilePath = dest.endsWith("/") ? dest + filename : dest + "/" + filename;
        File destFile = new File(destFilePath);
        if (destFile.exists()) {
            if (delOnExist) {
                destFile.delete();
            } else {
                new File(src).delete();
                return true;
            }
        }
        return new File(src).renameTo(destFile);
    }

    public static String join(String path, String name) {
        if (TextUtils.isEmpty(path)) {
            return name;
        }
        return path.endsWith("/") ? path + name : path + "/" + name;
    }

    public static void writeFile(String path, String name, boolean append, String content) {
        try {
            File dir = new File(path);
            if (!dir.exists()) {
                boolean mkdirs = dir.mkdirs();
                Logger.d("文件夹创建：" + mkdirs);
            }

            File file = new File(path, name);
            if (!file.exists()) {
                boolean newFile = file.createNewFile();
                Logger.d("文件创建：" + newFile);
            }

            FileWriter fileWriter = new FileWriter(file, append);
            fileWriter.append(content);
            fileWriter.close();
        } catch (Exception err) {
            Logger.error(err);
        }

    }

    public static String externalSDCardPath() {
        String externalPath = System.getenv("SECOENDARY_STORAGE");
        if (!TextUtils.isEmpty(externalPath)) {
            return externalPath;
        }

        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
            return "";
        }

        if (Build.VERSION.SDK_INT == Build.VERSION_CODES.M) {
            return extPathForM();
        }
        return extPathForNToLast();
    }


    private static String extPathForM() {
        String targetpath = "";
        StorageManager mStorageManager = (StorageManager) LApplication.app.getSystemService(Context.STORAGE_SERVICE);
        Class<?> storageVolumeClazz = null;
        try {
            storageVolumeClazz = Class.forName("android.os.storage.StorageVolume");

            Method getVolumeList = mStorageManager.getClass().getMethod("getVolumeList");

            Method getPath = storageVolumeClazz.getMethod("getPath");

            Object result = getVolumeList.invoke(mStorageManager);

            final int length = Array.getLength(result);

            Method getUserLabel = storageVolumeClazz.getMethod("getUserLabel");


            for (int i = 0; i < length; i++) {

                Object storageVolumeElement = Array.get(result, i);
                String userLabel = (String) getUserLabel.invoke(storageVolumeElement);
                String path = (String) getPath.invoke(storageVolumeElement);
                Logger.d(path);
                if (!TextUtils.isEmpty(userLabel) && !"内部存储设备".contains(userLabel)) {
                    targetpath = path;
                }

            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        return targetpath;
    }

    private static String extPathForNToLast() {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
            return "";
        }
        try {
            StorageManager storageManager = (StorageManager) LApplication.app.getSystemService(Context.STORAGE_SERVICE);
            // 7.0才有的方法
            List<StorageVolume> storageVolumes = storageManager.getStorageVolumes();
            Class<?> volumeClass = Class.forName("android.os.storage.StorageVolume");
            Method getPath = volumeClass.getDeclaredMethod("getPath");
            Method isRemovable = volumeClass.getDeclaredMethod("isRemovable");
            getPath.setAccessible(true);
            isRemovable.setAccessible(true);
            for (int i = 0; i < storageVolumes.size(); i++) {
                StorageVolume storageVolume = storageVolumes.get(i);
                String mPath = (String) getPath.invoke(storageVolume);
                Boolean isRemove = (Boolean) isRemovable.invoke(storageVolume);
                Logger.d("mPath is === " + mPath + "isRemoveble == " + isRemove);
                if (isRemove != null && isRemove && !TextUtils.isEmpty(mPath) && new File(mPath).exists()) {
                    return mPath;
                }
            }
        } catch (Exception e) {
            Logger.error(e);
        }
        return "";
    }
}
